4. 도커 개요2
2.2. 다양한 컨테이너 실행 방법
핵심 개념
컨테이너는 기본적으로 호스트와 격리된 환경에서 실행되지만, 실무에서는 데이터 공유, 네트워크 통신, 여러 컨테이너 조합 등 다양한 요구사항이 있음.
컨테이너 실행 고급 기능:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[기본 격리 환경]
↓
[확장 기능]
│
├─ 파일 공유
│ └─ 바인드 마운트, 볼륨
│
├─ 네트워크 공개
│ └─ 포트 포워딩
│
└─ 다중 컨테이너 관리
└─ Docker Compose
목표:
→ 데이터 영속성 확보
→ 외부 통신 활성화
→ 컨테이너 간 협업
2.2.1. 호스트와 컨테이너의 파일 공유와 데이터 유지
문제 상황
컨테이너 파일시스템의 한계:
컨테이너 격리로 인한 제약:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[호스트 OS]
├─ /home/user/data
└─ /var/log/app
✗ 컨테이너에서 접근 불가
[컨테이너]
├─ /app/data
└─ /var/log
✗ 컨테이너 삭제 시 데이터 손실
문제점:
→ 컨테이너는 독립된 루트 파일시스템 보유
→ 컨테이너 종료/삭제 시 내부 데이터 소멸
→ 호스트 파일에 직접 접근 불가
→ 컨테이너 간 파일 공유 불가
해결 방법1: 바인드 마운트
호스트 파일/디렉터리를 컨테이너에 연결:
바인드 마운트 개념:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[호스트 OS]
│
└─ /tmp/test/
└─ file.txt
↓ 마운트
[컨테이너]
│
└─ /mnt/
└─ file.txt (동일 파일)
특징:
→ 호스트와 컨테이너가 같은 파일 공유
→ 양방향 동기화 (읽기/쓰기)
→ 컨테이너 삭제해도 호스트 파일 유지
바인드 마운트 실습:
# 1. 호스트에 테스트 디렉터리 생성
mkdir C:\tmp\test
echo "Hello from host" > C:\tmp\test\host.txt
# 2. 바인드 마운트로 컨테이너 실행
docker run -it --name bind-test -v C:\tmp\test:/mnt:ro ubuntu:22.04 /bin/bash
명령어 구조:
docker run -v 옵션 설명:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
docker run -v /tmp/test:/mnt:ro ubuntu:22.04
│ │ │ │
│ │ │ └─ 마운트 옵션
│ │ │ ro: 읽기 전용
│ │ │ rw: 읽기/쓰기 (기본값)
│ │ │
│ │ └─ 컨테이너 내부 경로
│ │ (마운트 포인트)
│ │
│ └─ 호스트 경로
│ (소스 디렉터리)
│
└─ 볼륨/바인드 마운트 옵션
경로 규칙:
→ 절대 경로 사용 필수
→ 호스트:컨테이너 순서
→ 콜론(:)으로 구분
컨테이너 내부에서 확인:
# 컨테이너 쉘에서 실행
cd /mnt
ls
# 출력: host.txt
cat host.txt
# 출력: Hello from host
# 읽기 전용 확인
cat "test" > /mnt/test.txt
# 오류: Read-only file system
바인드 마운트 활용 시나리오:
실무 사용 예시:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[개발 환경]
docker run -v ${PWD}:/app myapp
│
└─ 소스 코드 실시간 반영
코드 수정 즉시 컨테이너에 반영
[로그 수집]
docker run -v /var/log/app:/logs myapp
│
└─ 컨테이너 로그를 호스트에 저장
모니터링 도구에서 로그 분석
[설정 파일 주입]
docker run -v ./config.yml:/etc/app/config.yml:ro myapp
│
└─ 환경별 설정 동적 주입
이미지 재빌드 없이 설정 변경
해결 방법2: 볼륨
도커가 관리하는 영속 스토리지:
볼륨 vs 바인드 마운트:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[바인드 마운트]
호스트 경로: /home/user/data
↓ 직접 지정
컨테이너 경로: /app/data
특징:
→ 호스트 경로를 명시적으로 지정
→ 파일/디렉터리 모두 가능
→ 호스트에서 직접 접근 가능
[볼륨]
볼륨 이름: my-volume
↓ 도커가 관리
호스트 경로: /var/lib/docker/volumes/my-volume/_data
↓ 자동 마운트
컨테이너 경로: /app/data
특징:
→ 도커가 위치 자동 관리
→ 디렉터리만 가능
→ docker volume 명령어로 관리
→ 컨테이너 간 공유 용이
볼륨 생성 및 사용:
# 1. 명시적 볼륨 생성 (선택사항)
docker volume create shared-vol
# 2. 볼륨 목록 확인
docker volume ls
볼륨 마운트 실습:
# 첫 번째 컨테이너에서 데이터 작성
docker run -it --name test-vol -v shared-vol:/mnt ubuntu:22.04 /bin/bash
컨테이너 내부에서 작업:
# shared-vol 볼륨에 파일 작성
echo "Hello" > /mnt/hello
# 컨테이너 로컬에만 파일 작성
echo "test" > /test
# 확인
ls /mnt # hello 파일 존재
ls / # test 파일 존재
다른 컨테이너에서 볼륨 공유 확인:
# 동일한 볼륨을 읽기 전용으로 마운트
docker run -it --name test-vol-2 -v shared-vol:/mnt:ro ubuntu:22.04 /bin/bash
두 번째 컨테이너 내부:
# 첫 번째 컨테이너에서 작성한 파일 읽기
cat /mnt/hello
# 출력: Hello
# test 파일은 보이지 않음 (첫 번째 컨테이너 로컬 파일)
cat /test
# 오류: No such file or directory
# 읽기 전용 확인
echo "hi" > /mnt/hi
# 오류: Read-only file system
볼륨 공유 메커니즘:
여러 컨테이너의 볼륨 공유:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Docker 볼륨: shared-vol]
│
├─→ [컨테이너 1: test-vol]
│ └─ /mnt (읽기/쓰기)
│ └─ hello 파일 작성
│
└─→ [컨테이너 2: test-vol-2]
└─ /mnt (읽기 전용)
└─ hello 파일 읽기
데이터 흐름:
1. test-vol에서 /mnt/hello 작성
2. shared-vol에 저장
3. test-vol-2에서 /mnt/hello 읽기 가능
장점:
→ 컨테이너 간 데이터 공유
→ 컨테이너 삭제해도 볼륨 유지
→ 데이터 영속성 보장
볼륨 생명주기 관리
볼륨 정리 작업:
# 컨테이너 중지
docker stop test-vol test-vol-2
# 컨테이너 삭제
docker rm test-vol test-vol-2
# 볼륨 목록 확인 (여전히 존재)
docker volume ls
# 출력: shared-vol 존재
# 볼륨 상세 정보
docker volume inspect shared-vol
# 볼륨 삭제
docker volume rm shared-vol
# 미사용 볼륨 일괄 삭제
docker volume prune
볼륨 생명주기:
볼륨 라이프사이클:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[생성]
docker volume create my-vol
또는
docker run -v my-vol:/data (자동 생성)
↓
[사용]
여러 컨테이너에 마운트 가능
데이터 읽기/쓰기
↓
[유지]
컨테이너 삭제해도 볼륨 유지
↓
[삭제]
docker volume rm my-vol (명시적)
또는
docker volume prune (미사용)
핵심:
→ 컨테이너와 독립적인 생명주기
→ 명시적으로 삭제하기 전까지 유지
→ 데이터 영속성 확보
바인드 마운트 vs 볼륨 선택 가이드:
사용 시나리오별 선택:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[바인드 마운트 사용]
✓ 개발 환경 (소스 코드 실시간 반영)
✓ 로그 파일 (호스트에서 직접 확인)
✓ 설정 파일 (특정 위치 지정 필요)
✓ 호스트 경로가 명확할 때
예시:
docker run -v ${PWD}/src:/app/src myapp
[볼륨 사용]
✓ 데이터베이스 데이터 (영속성)
✓ 컨테이너 간 데이터 공유
✓ 프로덕션 환경 데이터 저장
✓ 도커가 위치 관리해도 될 때
예시:
docker run -v db-data:/var/lib/mysql mysql
추천:
→ 개발: 바인드 마운트
→ 프로덕션: 볼륨
마운트 (Mount): 파일시스템을 특정 경로에 연결하는 것. 외부 저장소를 디렉터리처럼 사용 가능하게 함.
바인드 마운트 (Bind Mount): 호스트의 특정 경로를 컨테이너에 직접 연결. 호스트 파일 변경 시 컨테이너에 즉시 반영됨.
볼륨 (Volume): 도커가 관리하는 데이터 저장 공간. /var/lib/docker/volumes/에 위치함.
영속성 (Persistence): 데이터가 프로세스 종료 후에도 유지되는 특성. 컨테이너 삭제 후에도 데이터 보존됨.
2.2.2. 컨테이너 포트를 호스트에서 공개하기
네트워크 격리 문제
컨테이너의 독립 네트워크:
컨테이너 네트워크 격리:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[호스트 OS]
├─ IP: 192.168.1.100
└─ Port: 8080
✗ 컨테이너가 사용 불가
[컨테이너]
├─ IP: 172.17.0.2 (독립적)
└─ Port: 80
✗ 외부에서 접근 불가
문제:
→ 컨테이너는 독립된 네트워크 인터페이스 보유
→ 호스트와 다른 IP 주소 할당
→ 기본적으로 외부에서 컨테이너 접근 불가
포트 포워딩 (Port Publishing)
호스트 포트와 컨테이너 포트 연결:
포트 공개 메커니즘:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[외부 클라이언트]
↓ 요청
http://localhost:8080
↓
[호스트: 127.0.0.1:8080]
↓ 포트 포워딩
[컨테이너: 172.17.0.2:80]
↓
[NGINX 서버]
↓ 응답
[외부 클라이언트]
동작 원리:
→ 호스트 포트로 들어온 트래픽
→ 도커가 컨테이너 포트로 전달
→ 컨테이너에서 응답 생성
→ 도커가 호스트를 통해 응답 반환
포트 공개 실습
NGINX 웹 서버 실행:
# NGINX 컨테이너를 백그라운드로 실행
docker run -d --name nginx-sample -p 127.0.0.1:8080:80 nginx:1.25
명령어 구조:
docker run -p 옵션 설명:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
docker run -d -p 127.0.0.1:8080:80 nginx:1.25
│ │ │ │
│ │ │ └─ 컨테이너 포트
│ │ │ (NGINX 리스닝 포트)
│ │ │
│ │ └─ 호스트 포트
│ │ (외부 접근 포트)
│ │
│ └─ 바인드 IP
│ (접근 허용 주소)
│
└─ 포트 공개 옵션
-d: Detached 모드 (백그라운드 실행)
바인드 IP 옵션:
├─ 127.0.0.1: 로컬호스트만 (보안)
├─ 0.0.0.0: 모든 인터페이스 (외부 접근)
└─ 생략: 0.0.0.0 기본값
다양한 포트 매핑 형식:
포트 매핑 패턴:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[기본 형식]
-p 127.0.0.1:8080:80
→ 127.0.0.1의 8080포트를 컨테이너 80포트로 연결
[IP 생략]
-p 8080:80
→ 모든 IP의 8080포트를 컨테이너 80포트로 연결
→ 외부에서도 접근 가능 (주의!)
[호스트 포트 자동 할당]
-p 80
→ 컨테이너 80포트를 호스트의 임의 포트로 연결
→ docker port 명령어로 확인
[여러 포트 공개]
-p 8080:80 -p 8443:443
→ HTTP(80), HTTPS(443) 동시 공개
[UDP 포트]
-p 53:53/udp
→ DNS 등 UDP 프로토콜
접속 확인:
# PowerShell에서 웹 요청 (보안 경고 없이)
Invoke-WebRequest -Uri http://127.0.0.1:8080 -UseBasicParsing
# 또는 curl.exe 사용
curl.exe http://127.0.0.1:8080
# 브라우저로 접속
# http://127.0.0.1:8080
포트 매핑 확인:
# 컨테이너의 포트 매핑 정보 확인
docker port nginx-sample
# 출력 예시:
# 80/tcp -> 127.0.0.1:8080
정리 작업:
# 컨테이너 중지 및 삭제
docker stop nginx-sample
docker rm nginx-sample
보안 고려사항
포트 공개 시 주의사항:
보안 베스트 프랙티스:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[위험한 설정]
docker run -p 3306:3306 mysql
↓
모든 IP에서 MySQL 접근 가능
외부 공격에 노출
[안전한 설정]
docker run -p 127.0.0.1:3306:3306 mysql
↓
로컬호스트에서만 접근 가능
외부 차단
권장사항:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[개발 환경]
→ 127.0.0.1 바인딩 사용
→ 필요한 포트만 공개
→ 테스트 후 즉시 중지
[프로덕션 환경]
→ 리버스 프록시 사용 (NGINX, Traefik)
→ 방화벽 규칙 설정
→ TLS/SSL 인증서 적용
→ 최소 권한 원칙
예시:
# 개발
docker run -p 127.0.0.1:8080:80 myapp
# 프로덕션
docker run -p 127.0.0.1:8080:80 myapp
+ NGINX 리버스 프록시
+ Certbot SSL
실무 네트워크 구성:
프로덕션 네트워크 아키텍처:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[인터넷]
↓
[NGINX 리버스 프록시] :80, :443
↓ 내부 네트워크
[Docker 컨테이너들]
├─ Web App: 127.0.0.1:8080
├─ API Server: 127.0.0.1:3000
└─ Database: 127.0.0.1:5432 (공개 안 함)
계층화:
1. 외부: NGINX만 공개 (80, 443)
2. 내부: 컨테이너들은 localhost에만 바인딩
3. DB: 포트 공개 없이 도커 네트워크로만 통신
포트 포워딩 (Port Forwarding): 특정 포트로 들어온 트래픽을 다른 포트로 전달. 호스트 → 컨테이너 통신 연결에 사용됨.
리버스 프록시 (Reverse Proxy): 클라이언트 요청을 받아 내부 서버로 전달하는 서버. NGINX, Traefik 등이 대표적임.
TLS/SSL: TLS(Transport Layer Security)는 네트워크 통신 암호화 프로토콜. SSL(Secure Sockets Layer)은 TLS의 이전 명칭이며 현재는 TLS를 사용함.
Detached 모드 (-d): 컨테이너를 백그라운드에서 실행. 터미널 점유 없이 실행 지속됨.
2.2.3. 컴포즈: 여러 컨테이너를 한꺼번에 관리하기
Docker Compose 개념
다중 컨테이너 관리의 필요성:
컨테이너 조합의 복잡성:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[단일 명령어 방식의 한계]
docker run -d --name db mysql
docker run -d --name web --link db myapp
docker run -d --name nginx -p 80:80 nginx
문제점:
→ 실행 순서 고려 필요
→ 각 컨테이너별 명령어 개별 실행
→ 설정 관리 어려움
→ 재현성 낮음
[Compose 방식]
docker compose up
↓
모든 컨테이너 자동 실행
올바른 순서 보장
설정 파일로 관리
장점:
→ 명령어 1개로 전체 관리
→ YAML 파일로 설정 버전 관리
→ 개발/테스트 환경 재현 용이
Docker Compose 작업 흐름:
Compose 사용 흐름:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[1단계] compose.yml 작성
↓
services:
web:
image: myapp
db:
image: mysql
[2단계] 빌드 (필요시)
↓
docker compose build
[3단계] 실행
↓
docker compose up
[4단계] 중지 및 삭제
↓
docker compose down
핵심 명령어:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
build : 이미지 빌드
up : 컨테이너 생성 및 시작
down : 컨테이너 중지 및 삭제
ps : 컨테이너 상태 확인
logs : 로그 확인
Compose vs Kubernetes
스코프 차이:
도구 비교:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[Docker Compose]
범위: 단일 머신
대상: 소규모 애플리케이션
용도: 개발, 테스트, 소규모 배포
[호스트 머신]
├─ 컨테이너 1
├─ 컨테이너 2
└─ 컨테이너 3
특징:
→ 설정 간단
→ 로컬 개발에 최적
→ 학습 곡선 낮음
[Kubernetes]
범위: 여러 머신 (클러스터)
대상: 대규모 분산 시스템
용도: 프로덕션 운영
[클러스터]
├─ 노드 1
│ ├─ Pod A
│ └─ Pod B
├─ 노드 2
│ ├─ Pod C
│ └─ Pod D
└─ 노드 3
└─ Pod E
특징:
→ 고가용성
→ 자동 스케일링
→ 학습 곡선 높음
선택 기준:
→ 개발/테스트: Docker Compose
→ 프로덕션 소규모: Docker Compose
→ 프로덕션 대규모: Kubernetes
WordPress + MariaDB 실습
프로젝트 준비:
# 1. 프로젝트 디렉터리 생성
mkdir wordpress
cd wordpress
Compose 파일 작성:
# 2. compose.yml 파일 생성
@"
services:
wordpress:
image: wordpress:6.3
restart: always
ports:
- 127.0.0.1:8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
db:
image: mariadb:11.1
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
"@ | Set-Content compose.yml -Encoding UTF8
Compose 파일 구조 분석:
compose.yml 구조:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[최상위 요소]
│
├─ services
│ └─ 실행할 컨테이너 정의
│
└─ volumes
└─ 공유 볼륨 정의
[services 섹션]
│
├─ wordpress
│ ├─ image: 사용할 이미지
│ ├─ restart: 재시작 정책
│ ├─ ports: 포트 매핑
│ ├─ environment: 환경 변수
│ └─ volumes: 볼륨 마운트
│
└─ db
├─ image: mariadb:11.1
├─ environment: DB 설정
└─ volumes: 데이터 저장
[volumes 섹션]
├─ wordpress: 웹 파일 저장
└─ db: 데이터베이스 저장
주요 설정 상세 설명:
설정 항목 분석:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[wordpress 서비스]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
image: wordpress:6.3
└─ Docker Hub의 WordPress 공식 이미지
restart: always
└─ 컨테이너 중지 시 자동 재시작
├─ no: 재시작 안 함
├─ always: 항상 재시작
├─ on-failure: 오류 시만 재시작
└─ unless-stopped: 수동 중지 전까지 재시작
ports:
- 127.0.0.1:8080:80
└─ 호스트 8080 → 컨테이너 80
environment:
WORDPRESS_DB_HOST: db
└─ 서비스명이 호스트명으로 작동
db 컨테이너를 "db"로 접근 가능
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
└─ MariaDB 연결 정보
volumes:
- wordpress:/var/www/html
└─ 명명된 볼륨 마운트
WordPress 파일 영속화
[db 서비스]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
environment:
MYSQL_DATABASE: exampledb
└─ 초기 데이터베이스 생성
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
└─ 사용자 계정 생성
MYSQL_RANDOM_ROOT_PASSWORD: '1'
└─ root 비밀번호 랜덤 생성
(보안 향상)
volumes:
- db:/var/lib/mysql
└─ 데이터베이스 데이터 영속화
서비스 간 네트워크 통신:
Compose 네트워크:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[자동 생성된 Docker 네트워크]
│
├─ wordpress 컨테이너
│ └─ 호스트명: wordpress
│ └─ WORDPRESS_DB_HOST=db로 접속
│
└─ db 컨테이너
└─ 호스트명: db
└─ MySQL 3306 포트 리스닝
통신 방식:
wordpress 컨테이너 → db:3306 → MariaDB
특징:
→ 서비스명이 DNS로 작동
→ 같은 Compose 프로젝트 내에서만 통신
→ 외부 노출 없이 내부 통신 가능
볼륨 영속화:
데이터 영속성 보장:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[wordpress 볼륨]
↓ 마운트
wordpress 컨테이너: /var/www/html
↓ 저장
├─ WordPress 코어 파일
├─ 테마
├─ 플러그인
└─ 업로드 파일
[db 볼륨]
↓ 마운트
db 컨테이너: /var/lib/mysql
↓ 저장
├─ 데이터베이스 파일
├─ 테이블 데이터
└─ 트랜잭션 로그
결과:
→ docker compose down 해도 데이터 유지
→ 컨테이너 재생성 시 데이터 복원
→ 업그레이드 시에도 데이터 보존
Compose 실행 및 관리
컨테이너 실행:
# compose.yml이 있는 디렉터리에서 실행
docker compose up -d
실행 과정:
docker compose up 동작:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[1단계] 네트워크 생성
↓
wordpress_default 네트워크 생성
└─ {프로젝트명}_default 패턴
[2단계] 볼륨 생성
↓
wordpress_wordpress 볼륨 생성
wordpress_db 볼륨 생성
└─ {프로젝트명}_{볼륨명} 패턴
프로젝트명 결정:
→ 디렉터리명 사용 (wordpress/)
→ compose.yml의 volumes에서 정의한 이름에 접두사 추가
[3단계] 이미지 다운로드
↓
wordpress:6.3 Pull
mariadb:11.1 Pull
[4단계] 컨테이너 생성
↓
wordpress_db_1 생성 (먼저)
wordpress_wordpress_1 생성 (의존성 고려)
└─ {프로젝트명}_{서비스명}_{인스턴스} 패턴
[5단계] 컨테이너 시작
↓
db 컨테이너 시작
wordpress 컨테이너 시작
[-d 옵션]
→ Detached 모드 (백그라운드 실행)
→ 로그 출력 없이 즉시 반환
네이밍 규칙 요약:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
→ 컨테이너: {프로젝트명}_{서비스명}_{번호}
→ 볼륨: {프로젝트명}_{볼륨명}
→ 네트워크: {프로젝트명}_{네트워크명}
→ 프로젝트명: 디렉터리명 (기본값)
상태 확인:
# 실행 중인 컨테이너 확인
docker compose ps
# 로그 확인
docker compose logs
# 특정 서비스 로그
docker compose logs wordpress
# 실시간 로그 스트리밍
docker compose logs -f
서비스 접속:
# 브라우저에서 접속
# http://127.0.0.1:8080
# 또는 PowerShell에서 확인 (보안 경고 없이)
Invoke-WebRequest -Uri http://127.0.0.1:8080 -UseBasicParsing
WordPress 초기 설정:
브라우저 접속 후:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. 언어 선택
2. 사이트 정보 입력
├─ 사이트 제목
├─ 관리자 ID
└─ 비밀번호
3. WordPress 설치 완료
4. 데이터베이스 연결 자동 설정
(compose.yml의 환경 변수 사용)
서비스 중지 및 삭제:
# 컨테이너 중지 및 삭제
docker compose down
# 볼륨까지 삭제 (주의: 데이터 손실)
docker compose down -v
down 명령어 동작:
docker compose down:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[기본 down]
↓
컨테이너 중지 및 삭제
네트워크 삭제
볼륨은 유지 ← 데이터 보존
[down -v]
↓
컨테이너 삭제
네트워크 삭제
볼륨도 삭제 ← 데이터 손실
선택:
→ 개발 중: down (볼륨 유지)
→ 완전 초기화: down -v
Compose 고급 기능
유용한 Compose 명령어:
# 이미지 빌드만 실행
docker compose build
# 특정 서비스만 실행
docker compose up -d wordpress
# 서비스 스케일링
docker compose up -d --scale wordpress=3
# 컨테이너 재시작
docker compose restart
# 서비스 중지 (삭제하지 않음)
docker compose stop
# 서비스 시작 (기존 컨테이너)
docker compose start
# 실행 중인 컨테이너에서 명령어 실행
docker compose exec wordpress bash
docker compose exec db mysql -u root -p
Compose 파일 확장 예시:
# 더 복잡한 구성 예시
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- wordpress
wordpress:
image: wordpress:6.3
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: ${DB_USER} # 환경 변수 사용
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
volumes:
- wordpress:/var/www/html
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
depends_on:
db:
condition: service_healthy # 헬스체크 대기
db:
image: mariadb:11.1
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
volumes:
- db:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:alpine
restart: always
volumes:
wordpress:
db:
networks:
default:
driver: bridge
환경 변수 파일 (.env):
# .env 파일 생성
@"
DB_USER=wpuser
DB_PASSWORD=secure_password
MYSQL_ROOT_PASSWORD=root_secure_password
"@ | Set-Content .env
YAML: 사람이 읽기 쉬운 데이터 직렬화 형식. 들여쓰기로 계층 구조 표현하며 compose.yml, Kubernetes 설정 등에 사용됨.
헬스체크 (Health Check): 컨테이너/서비스의 정상 동작 여부 확인. 주기적으로 상태 점검 명령을 실행함.
depends_on: Compose에서 서비스 시작 순서 지정. 의존하는 서비스가 먼저 시작됨.
핵심 요약
다양한 컨테이너 실행 방법 정리:
2.2장 핵심 개념:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[파일 공유 및 데이터 유지]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
바인드 마운트:
docker run -v /host/path:/container/path myapp
→ 호스트 경로 직접 지정
→ 개발 환경 소스 코드 반영
→ 로그, 설정 파일 공유
볼륨:
docker run -v volume-name:/container/path myapp
→ 도커가 위치 관리
→ 컨테이너 간 데이터 공유
→ 영속성 보장
선택 기준:
├─ 개발: 바인드 마운트 (실시간 반영)
└─ 프로덕션: 볼륨 (안정성)
[포트 공개]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
포트 포워딩:
docker run -p 127.0.0.1:8080:80 nginx
→ 호스트 포트를 컨테이너 포트로 연결
→ 외부에서 컨테이너 서비스 접근
보안:
├─ 127.0.0.1: 로컬만 (권장)
├─ 0.0.0.0: 모든 IP (주의)
└─ 필요한 포트만 최소 공개
[Docker Compose]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
다중 컨테이너 관리:
docker compose up -d
→ YAML 파일로 전체 구성 정의
→ 명령어 1개로 모든 서비스 실행
→ 의존성 자동 처리
주요 명령어:
├─ up: 실행
├─ down: 중지 및 삭제
├─ ps: 상태 확인
├─ logs: 로그 확인
└─ exec: 컨테이너 내부 명령 실행
사용 시나리오:
├─ 개발 환경 구성
├─ 마이크로서비스 로컬 테스트
└─ 소규모 프로덕션 배포
vs Kubernetes:
├─ Compose: 단일 머신
└─ Kubernetes: 다중 머신 클러스터
실무 팁:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[개발 환경]
→ Compose로 전체 스택 실행
→ 바인드 마운트로 코드 반영
→ 127.0.0.1로 포트 제한
[프로덕션]
→ 볼륨으로 데이터 영속화
→ restart: always 설정
→ 환경 변수로 설정 분리
→ 헬스체크 구성
결론:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
→ 바인드 마운트/볼륨: 데이터 관리
→ 포트 공개: 네트워크 통신
→ Compose: 복잡도 관리
→ 조합하여 실무 환경 구축
참고 자료
공식 문서:
- Docker Volumes: https://docs.docker.com/storage/volumes/
- Bind Mounts: https://docs.docker.com/storage/bind-mounts/
- Docker Compose: https://docs.docker.com/compose/
- Networking Overview: https://docs.docker.com/network/
Compose 관련:
- Compose File Reference: https://docs.docker.com/compose/compose-file/
- Compose Networking: https://docs.docker.com/compose/networking/